package cn.myjerry.test.javassist;

import java.lang.reflect.Method;
import java.util.Arrays;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtField;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.Modifier;

/**
 * 测试javassist的API
 * @author Jerry
 *
 */
public class Demo02 {
	
	public static void test01() throws Exception {
		ClassPool pool = ClassPool.getDefault();
		CtClass cc = pool.get("cn.myjerry.test.javassist.Emp");
		
		byte[] bytes = cc.toBytecode();
		System.out.println(Arrays.toString(bytes));
		
		System.out.println(cc.getName());	// 获得类名
		System.out.println(cc.getSimpleName());		// 获得简要类名
		System.out.println(cc.getSuperclass());		// 获得父类
		System.out.println(cc.getInterfaces());		// 获得接口
	}
	
	/**
	 * 测试产生新的方法
	 * @throws Exception
	 */
	public static void test02() throws Exception {
		ClassPool pool = ClassPool.getDefault();
		CtClass cc = pool.get("cn.myjerry.test.javassist.Emp");
		
//		CtMethod cm1 = CtMethod.make("public int add(int a, int b){return a + b;}", cc);
		
		CtMethod cm = new CtMethod(CtClass.intType, "add",
				new CtClass[]{CtClass.intType, CtClass.intType}, cc);
		cm.setModifiers(Modifier.PUBLIC);
		cm.setBody("{System.out.println(\"www.myjerry.cn\");return $1 + $2;}");
		cc.addMethod(cm);
		
		Class clazz = cc.toClass();
		Object obj = clazz.newInstance();
		Method m = clazz.getDeclaredMethod("add", int.class, int.class);
		Object result = m.invoke(obj, 10, 20);
		System.out.println(result);
	}
	
	/**
	 * 修改已有的方法
	 * @throws Exception
	 */
	public static void test03() throws Exception {
		ClassPool pool = ClassPool.getDefault();
		CtClass cc = pool.get("cn.myjerry.test.javassist.Emp");
		
		CtMethod cm = cc.getDeclaredMethod("sayHolle", new CtClass[]{CtClass.intType});
		cm.insertAfter("System.out.println(\"after\");");
		cm.insertAt(15, "System.out.println(\"center\");");
		cm.insertBefore("System.out.println(\"before\");");
		
		Class clazz = cc.toClass();
		Object obj = clazz.newInstance();
		Method m = clazz.getDeclaredMethod("sayHolle", int.class);
		Object result = m.invoke(obj, 10);
		System.out.println(result);
	}
	
	/**
	 * 属性的操作
	 * @throws Exception
	 */
	public static void test04() throws Exception {
		ClassPool pool = ClassPool.getDefault();
		CtClass cc = pool.get("cn.myjerry.test.javassist.Emp");
		
//		CtField sf1 = CtField.make("private int No;", cc);
		CtField sf1 = new CtField(CtClass.intType, "Salary", cc);
		sf1.setModifiers(Modifier.PUBLIC);
		cc.addField(sf1);

		cc.addMethod(CtNewMethod.getter("getSalary", sf1));
		cc.addMethod(CtNewMethod.getter("setSalary", sf1));
	}
	
	/**
	 * 构造器方法的操作
	 * @throws Exception
	 */
	public static void test05() throws Exception {
		ClassPool pool = ClassPool.getDefault();
		CtClass cc = pool.get("cn.myjerry.test.javassist.Emp");
	
		CtConstructor[] cs = cc.getConstructors();
		for(CtConstructor c:cs) {
			System.out.println(c.getLongName());
		}
	}
	
	public static void main(String[] args) throws Exception {
		test05();
	}
}
